﻿using System.Data;
using System.Text;

namespace ExcelToJson
{
    /// <summary>
    /// 根据表头，生成C#类定义数据结构
    /// 表头使用三行定义：字段名称、字段类型、注释
    /// </summary>
    internal class CSDefineGenerator
    {
        private struct FieldDef
        {
            public string name;
            public string type;
            public string comment;
            public string platform;
        }

        private List<FieldDef> m_fieldList;

        public string ClassComment
        {
            get;
            set;
        }

        /// <summary>
        /// 当前的目标平台
        /// </summary>
        private string CurTargetPlatform;

        public CSDefineGenerator(DataTable sheet, int headRowCount, string targetPlatform)
        {
            //-- First Row as Column Name
            if (sheet.Rows.Count < headRowCount)
            {
                return;
            }

            CurTargetPlatform = targetPlatform;

            m_fieldList = new List<FieldDef>();
            DataRow fieldNameRow = sheet.Rows[0];
            DataRow typeRow = sheet.Rows[1];
            DataRow platformRow = sheet.Rows[2];
            DataRow commentRow = sheet.Rows[3];

            foreach (DataColumn column in sheet.Columns)
            {
                if (typeRow[column].ToString() == "")
                {
                    continue;
                }

                FieldDef field;
                field.name = fieldNameRow[column].ToString();

                string typeStr = typeRow[column].ToString();

                if (typeStr == "bool[]")//bool数组改为int数组
                {
                    typeStr = "int[]";
                }
                field.type = typeStr;

                string platform = (platformRow[column].ToString() == "") ? "all" : platformRow[column].ToString();
                field.platform = platform;
                field.comment = commentRow[column].ToString();

                m_fieldList.Add(field);
            }
        }

        public void SaveToFile(string filePath, Encoding encoding)
        {
            if (m_fieldList == null)
                throw new Exception("CSDefineGenerator内部数据为空。");

            string defName = Path.GetFileNameWithoutExtension(filePath);

            //-- 创建代码字符串
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("// Auto Generated Code By excel2json");

            //excel源文件名称
            if (this.ClassComment != null)
            {
                sb.AppendLine(this.ClassComment);
            }

            //Using引入
            sb.AppendLine("\nusing System;");
            //sb.AppendLine("using System.Collections.Generic;\n");

            //Namespace
            if (!string.IsNullOrEmpty(Program.CurOption.CSharpPackage))
            {
                sb.AppendFormat("namespace " + Program.CurOption.CSharpPackage + "\n");
            }
            sb.AppendLine("{");

            //DataHolder类加入,用于Unity的JsonUtility反序列化
            sb.AppendLine("\t[Serializable]");
            sb.AppendFormat("\tpublic struct {0}{1}{2}\r", defName, "DataHolder", " : IConfigDataHolder");
            sb.AppendLine("\t{");
            sb.AppendFormat("\t\tpublic {0}[] configList;\n", defName);
            sb.AppendFormat("\n\t\tpublic Array GetConfigs()\n");
            sb.AppendLine("\t\t{\n\t\t\treturn configList;\n\t\t}");

            sb.AppendLine("\n\t\tpublic Type GetConfigType()");
            sb.AppendLine("\t\t{");
            sb.AppendFormat("\t\t\treturn typeof({0});\r", defName);
            sb.AppendLine("\t\t}");

            sb.AppendLine("\t}\n");

            //Class name
            sb.AppendLine("\t[Serializable]");
            sb.AppendFormat("\tpublic struct {0}{1}\r", defName, " : IConfig");
            sb.AppendLine("\t{");

            sb.AppendLine("\t\tpublic int GetId() {return Id;} ");

            foreach (FieldDef field in m_fieldList)
            {
                bool isConvert = false;
                if (field.platform == "all")
                {
                    isConvert = true;
                }
                else if (field.platform == "c" && CurTargetPlatform == "client")
                {
                    isConvert = true;
                }
                else if (field.platform == "s" && CurTargetPlatform == "server")
                {
                    isConvert = true;
                }

                if (isConvert)
                {
                    string comment = field.comment.Replace("\n", " ");
                    string srt = "\t\t/// <summary>\n\t\t///" + comment + "\n\t\t/// </summary>\n" + "\t\tpublic " + field.type + " " + field.name + ";";// + "{set; get;}";
                    sb.AppendLine(srt);
                }

                sb.AppendLine();
            }
            sb.AppendLine("\t}");
            sb.AppendLine();
            sb.Append('}');
            sb.AppendLine();
            sb.AppendLine("// End of Auto Generated Code");

            //-- 保存文件
            using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                using (TextWriter writer = new StreamWriter(file, encoding))
                    writer.Write(sb.ToString());
            }
        }
    }
}